package com.alex.config.scope;

import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.config.Scope;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

@Configuration
public class ThreadLocalScope implements Scope {

    // 定义了作用域的名称为一个常量thread，可以在定义bean的时候给scope使用
    public static final String THREAD_SCOPE = "thread";

    private ThreadLocal<Map<String, Object>> beanMap = ThreadLocal.withInitial(HashMap::new);

    @Override
    public Object get(String name, ObjectFactory<?> objectFactory) {
        Object bean = beanMap.get().get(name);
        if (Objects.isNull(bean)) {
            bean = objectFactory.getObject();
            beanMap.get().put(name, bean);
        }

        return bean;
    }

    @Override
    public Object remove(String name) {
        return this.beanMap.get().remove(name);
    }

    @Override
    public void registerDestructionCallback(String name, Runnable runnable) {
        // bean作用域结束的时候调用的方法, 用于bean清理
        System.out.println(name);
    }

    @Override
    public Object resolveContextualObject(String name) {
        return null;
    }

    @Override
    public String getConversationId() {
        return Thread.currentThread().getName();
    }

    @org.springframework.context.annotation.Scope(ThreadLocalScope.THREAD_SCOPE)
    @Bean(value = "threadBean")
    public BeanScopeModel beanScopeModel() {
        return new BeanScopeModel(ThreadLocalScope.THREAD_SCOPE);
    }
}
